home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 084 (1990-10)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 084 (1990-10)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / MakeC / makec.c < prev    next >
C/C++ Source or Header  |  1990-09-20  |  36KB  |  1,214 lines

  1. /*
  2.     MakeC Version 2.0
  3.     
  4.         This is an  update to MakeC version 1.9.  Most of the changes 
  5.     are pretty minor.  Some bugs have been squashed and some new features
  6.     have been added.
  7.     
  8.     Functional Changes:
  9.         
  10.         Slight problem in color palette decoding routine has been repaired.
  11.  
  12.         MakeC no longer hides the top portion of the picture being used
  13.     behind the title bar.  (Am I the only one who noticed this?)
  14.     
  15.         MakeC now supports display and manipulation of overscan pictures
  16.     without having to scroll around.
  17.     
  18.         MakeC now supports use of the "chip" keyword in the source output
  19.     in order to force data generated into chip memory.  I am not aware
  20.     of which particular compilers support this keyword, so you may want to
  21.     consult your manual.  This option is implemented by the -c switch on 
  22.     the command line.
  23.     
  24.     Other Changes:
  25.     
  26.         MakeC now has an improved look to its save/cancel/quit window.  It
  27.     makes use of simulated 3D gadgets and supports the look of the new
  28.     WorkBench 2.0.  It does _not_ require 2.0 to work, it just tries to 
  29.     look like it belongs under it...as far as  know, it works under
  30.     Kickstart/WorkBench 1.2 and later.
  31.  
  32.         I also made sure that all of the fonts are explicitly asked for
  33.     rather than accepting the default.  It works fine no matter what your
  34.     default font preferences are set up as...
  35. */
  36.  
  37. /*
  38.     MakeC v1.9
  39.     
  40.         Fixes a minor bug in the BitMap output (forgot a pad byte there).
  41. */
  42.  
  43. /*
  44.     MakeC v1.5
  45.  
  46.         This is a program to allow "clipping" parts of pictures into
  47.     C source code structures.  It will display an IFF picture or brush,
  48.     then allow the user to "clip" sections of it with the mouse.  The
  49.     section is then converted to C source code and written to a file.
  50.         The program runs from the CLI only (after all, if you're doing any
  51.     C programming, you are probably using the CLI anyway).
  52.         Syntax is:
  53.  
  54.         MakeC iff_file
  55.  
  56.     New version 1.5 now includes scrolling support for SuperBitMaps, as
  57.     well as gadget selection of output format.
  58.  
  59.     In order to get this thing to work, you have to link with iff_stuff.o.
  60. */
  61.  
  62.  
  63.  
  64. #include <stdio.h>
  65. #include <ctype.h>
  66. #include <string.h>
  67. #ifndef EXEC_TYPES_H
  68.     #include <exec/types.h>
  69. #endif
  70. #ifndef EXEC_PORTS_H
  71.     #include <exec/ports.h>
  72. #endif
  73. #ifndef EXEC_MEMORY_H
  74.     #include <exec/memory.h>
  75. #endif
  76. #ifndef INTUITION_INTUITION_H
  77.     #include <intuition/intuition.h>
  78. #endif
  79. #ifndef INTUITION_SCREENS_H
  80.     #include <intuition/screens.h>
  81. #endif
  82. #ifndef GRAPHICS_GFXMACROS_H
  83.     #include <graphics/gfxmacros.h>
  84. #endif
  85. #ifndef GRAPHICS_GFX_H
  86.     #include <graphics/gfx.h>
  87. #endif
  88. #include "iff.h"
  89.  
  90. char iffname[40];        /* iff filename                            */
  91.  
  92. UWORD colortable[64];        /* save color map for later...           */
  93. SHORT colorcount = 0;        /* and the color count...           */
  94.  
  95. FILE *ifffile = NULL;        /* This is the input picture           */
  96. FILE *outputfile = NULL;    /* This is the output source file(s).  */
  97.  
  98. BOOL chipkeyword = FALSE;    /* set to true for "chip" keyword out  */
  99.  
  100. BitMapHeader header;        /* This will hold the bitmap info...      */
  101.  
  102. struct Screen *screen = NULL;    /* This will be the screen for the picture */
  103. struct Window *window = NULL;    /* and the window to hold it      */
  104. struct BitMap *sbmap  = NULL;    /* and the actual bitmap */
  105. struct RastPort *rport;
  106.  
  107. struct Rectangle clip;        /* the desired clip                           */
  108.  
  109. BOOL IMAGE_OUT = FALSE;     /* flag for Image output                   */
  110.  
  111. struct GfxBase *GfxBase = NULL;     /* library stuff               */
  112. struct IntuitionBase *IntuitionBase = NULL;
  113. struct LayersBase *LayersBase = NULL;
  114.  
  115. BOOL OpenStuff(void);           /* some prototypes                                                 */
  116. void CloseStuff(void);
  117. void MakeItC(void);
  118. BOOL GetClip(struct Rectangle *clipit);
  119. UBYTE GetName(char *name);
  120. void RubberBand(struct Rectangle *clipit,BOOL show);
  121. void WriteCode(char *savename);
  122. void FindBaseName(char *base,char *name);
  123. void ImageOut(struct BitMap *map, char *basename,short width,short height, short depth);
  124. void BitMapOut(struct BitMap *map,char *basename,short width,short height, short depth);
  125. struct BitMap *create_bitmap(UWORD width, UWORD height, UBYTE depth);
  126. void close_bitmap(struct BitMap *bitmap);
  127.  
  128.  
  129. /*
  130.     Here's the main function. Doesn't seem to do a whole lot, does it?
  131. */
  132.  
  133. void main(argc,argv)
  134. int argc;
  135. char **argv;
  136. {
  137.     BOOL trouble = FALSE;
  138.  
  139.     if((argc<2) || (argv[1][0] == '?'))
  140.         {
  141.             printf("\n%s -- by Robert Kesterson",argv[0]);
  142.             printf("\nThis program creates C source code from IFF pictures.");
  143.             printf("\nThe picture is displayed as you clip areas with the mouse.");
  144.             printf("\nWhile the window is active, pressing 'b' sends the screen");
  145.             printf("\nto the back, 'f' brings it to the front, 'q' brings up the ");
  146.             printf("\nsave/cancel/quit window, and 'h' homes the picture.");
  147.             printf("\nfor further information, read the documentation.");
  148.             printf("\nUsage is:  %s [-c] iff_file.\n",argv[0]);
  149.             printf("\nThe -c switch will cause data structures output to use the \"chip\" ");
  150.             printf("\nkeyword to force data into chip memory.  Check your ");
  151.             printf("\ncompiler documentation to see if it supports this keyword.\n");
  152.             exit(0);
  153.         }
  154.     if(argc > 2)
  155.         {
  156.             if(argv[1][0] = '-')
  157.                 strcpy(iffname,argv[2]);
  158.             else 
  159.                 strcpy(iffname,argv[1]);
  160.             chipkeyword = TRUE;
  161.         }
  162.     else
  163.         strcpy(iffname,argv[1]);
  164.     trouble = OpenStuff();  /* open screen, window, file, libraries, etc */
  165.     if(!trouble)
  166.         MakeItC();                      /* do the clipping stuff */
  167.     CloseStuff();                   /* close everything down */
  168. }
  169.  
  170. /*
  171.     OpenStuff() is a rather bloated routine that tries to handle just about
  172.     everything.  It reads the IFF file and sets up a screen big enough to
  173.     hold it (according to the file's BitMapHeader).  Then it allocates
  174.     a bitmap for the image and opens a SuperBitMap window to put it in.
  175.     Then it sets the colormap for the screen and reads the picture into
  176.     the SuperBitMap.  Then it does some Layers fiddling to refresh the
  177.     initial window, and returns to the caller.
  178. */
  179.  
  180. BOOL OpenStuff()
  181. {
  182.     struct NewScreen newscreen;
  183.     struct NewWindow newwindow =
  184.         {
  185.             0,0,0,0,        /* left, top, width, height (fill in below) */
  186.             -1,-1,            /* use default pens */
  187.             MOUSEMOVE|MOUSEBUTTONS|VANILLAKEY,        /* IDCMP flags */
  188.             BACKDROP|RMBTRAP|SUPER_BITMAP|BORDERLESS|ACTIVATE|GIMMEZEROZERO|REPORTMOUSE,
  189.             NULL,            /* no gadgets */
  190.             NULL,            /* no checkmark */
  191.             NULL,            /* no title    */
  192.             NULL,            /* screen -- fill in below */
  193.             NULL,            /* not superbitmap  ...yet...  */
  194.             0,0,0,0,        /* max and min sizes */
  195.             CUSTOMSCREEN
  196.         };
  197.     BOOL error;
  198.     SHORT count;
  199.     BYTE hires=1, lace=1;
  200.  
  201.     for(count=0;count<64;count++)
  202.         colortable[count] = 0x0000;        /* initialize color table */
  203.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
  204.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
  205.     LayersBase = (struct Library *)OpenLibrary("layers.library",0);
  206.     if((!IntuitionBase) || (!GfxBase) || (!LayersBase))
  207.         return TRUE;        /*  Like maybe you yanked your ROMs out?  */
  208.     if((ifffile = fopen(iffname,"rb")) == NULL)
  209.         {                    /* hey dude, get the name right... */
  210.             printf("\nCan't open IFF file!!\n");
  211.             return TRUE;
  212.         }                    /* Open the IFF file and set up the screen */
  213.     error = GetBMHD(ifffile,&header);
  214.     if(error)
  215.         {
  216.             printf("\nFile error or invalid IFF file.\n");
  217.             return TRUE;
  218.         }
  219.     newscreen.LeftEdge = header.x;        /* figure out what the screen */
  220.     newscreen.TopEdge = header.y;        /* needs to look like */
  221.     newscreen.ViewModes = 0;
  222.     newscreen.Type = CUSTOMSCREEN | SCREENBEHIND | SCREENQUIET;
  223.     newscreen.Height = header.h;
  224.     newscreen.Width = header.w;
  225.     if(header.h < header.pageHeight)            /* is it a brush? */
  226.         newscreen.Height = (header.pageHeight > 240) ? 400 : 200;
  227.     else if(header.h > header.pageHeight)
  228.         newscreen.Height = header.pageHeight;    /* or a superbitmap? */
  229.     if(header.w < header.pageWidth)
  230.         newscreen.Width = (header.pageWidth > 384) ? 640 : 320;
  231.     else if(header.w > header.pageWidth)
  232.         newscreen.Width = header.pageWidth;
  233.     newscreen.Depth = header.nplanes;
  234.     newscreen.DetailPen = 0;
  235.     newscreen.BlockPen = 1;
  236.     newscreen.DefaultTitle = NULL;
  237.     newscreen.Gadgets = NULL;
  238.     newscreen.Font = NULL;                /* probably should declare one... */
  239.     newscreen.CustomBitMap = NULL;
  240.     error = GetViewModes(&newscreen, ifffile);
  241.     if(error)
  242.         {
  243.             printf("\nProblem with viewmodes!\n");
  244.             return TRUE;
  245.         }
  246.  
  247.         
  248.     if((newscreen.Width > 384) && (newscreen.Depth <= 4) && !(newscreen.ViewModes & HAM))        
  249.         {                                    /* this is redundant stuff here    */
  250.             newscreen.ViewModes |= HIRES;    /* but necessary to make the       */
  251.             hires = 2;                        /* newscreen structure come out    */
  252.         }                                    /* right since it's still evolving */
  253.     if(newscreen.Height > 200)            
  254.         {
  255.             newscreen.ViewModes |= LACE;    
  256.             lace = 2;
  257.         }
  258.     if(header.h > 200 * lace)
  259.         {            
  260.             newscreen.Height = 240 * lace;     /* center if overscan */
  261.             newscreen.TopEdge -= (newscreen.Height - (200 * lace)) / 2;
  262.         }
  263.     if(header.w > 352 * hires)                /* severe overscan? */
  264.         {
  265.             newscreen.Width = 384 * hires;     /* center it */
  266.             newscreen.LeftEdge -= (newscreen.Width - (320 * hires)) / 2;
  267.         }        
  268.     else if(header.w > 320 * hires)            /* normal overscan? */
  269.         {
  270.             newscreen.Width = 352 * hires;    /* center it */
  271.             newscreen.LeftEdge -= (newscreen.Width - (320 * hires)) / 2;
  272.         }
  273.     if((newscreen.Width > 384) && (newscreen.Depth <= 4) && !(newscreen.ViewModes & HAM))
  274.         newscreen.ViewModes |= HIRES;    
  275.     if(newscreen.Height > 200)                /* these might need to be   */
  276.         newscreen.ViewModes |= LACE;        /* changed, so just make sure */
  277.                                         
  278.     screen = (struct Screen *)OpenScreen(&newscreen);
  279.     if(!screen)
  280.         {                                    /* low on RAM, maybe? */
  281.             printf("\nCan't open the screen!\n");
  282.             return TRUE;
  283.         }
  284.     newwindow.Height = newscreen.Height;    /* make a screen-sized window */
  285.     newwindow.Width = newscreen.Width;
  286.     newwindow.Screen = screen;
  287.     sbmap = create_bitmap(header.w,header.h,header.nplanes);
  288.     if(sbmap == NULL)
  289.         {
  290.             printf("\nNo Memory for SuperBitMap!!\n");
  291.             return TRUE;
  292.         }
  293.     newwindow.BitMap = sbmap;                /* jam it into the window */
  294.     window = (struct Window *)OpenWindow(&newwindow);
  295.     if(!window)
  296.         {
  297.             printf("\nCan't open a window!!\n");
  298.             return TRUE;
  299.         }
  300.     rport = window->RPort;                        /* need this later */
  301.     colorcount = GetColorMap(ifffile,colortable);   /* fix the colors  */
  302.     LoadRGB4(&screen->ViewPort,colortable,colorcount);
  303.     error = ReadPic(sbmap,ifffile,&header);         /* read the image  */
  304.     if(error)
  305.         {
  306.             printf("\nError decoding IFF file!\n");
  307.             return TRUE;
  308.         }
  309.     LockLayerRom(window->WLayer);           /* refresh the window */
  310.     CopySBitMap(window->WLayer);            /* (only do it this way the */
  311.     UnlockLayerRom(window->WLayer);         /* first time.  After that, */
  312.     ScreenToFront(screen);                          /* Intuition handles it) */
  313.     ShowTitle(screen,FALSE);
  314.     return FALSE;
  315. }
  316.  
  317.  
  318. /*
  319.     CloseStuff() attempts to figure out all the garbage I didn't already
  320.     close somewhere and clean up after me.    Important when closing things
  321.     elsewhere to set them to NULL so they don't get re-closed here.  Good
  322.     way to get a lesson in meditation....
  323. */
  324.  
  325. void CloseStuff()
  326. {
  327.     if(ifffile)
  328.         fclose(ifffile);
  329.     if(sbmap)
  330.         close_bitmap(sbmap);
  331.     if(window)
  332.         CloseWindow(window);
  333.     if(screen)
  334.         CloseScreen(screen);
  335.     if(LayersBase)
  336.         CloseLibrary(LayersBase);
  337.     if(GfxBase)
  338.         CloseLibrary(GfxBase);
  339.     if(IntuitionBase)
  340.         CloseLibrary(IntuitionBase);
  341. }
  342.  
  343.  
  344. /*
  345.     MakeItC() lets you do the actual clipping of areas of the picture
  346.     It keeps track of your clip and your motion around the superbitmap
  347.     so things don't get confused.
  348. */
  349.  
  350. void MakeItC()
  351. {
  352.     UBYTE ready;
  353.     BOOL contin = TRUE;
  354.     char savename[41] = "C_clip";
  355.  
  356.     do
  357.         {
  358.             clip.MinX = clip.MinY = clip.MaxX = clip.MaxY = 0;
  359.             ready = GetClip(&clip);         /* get the real clip */
  360.             if(!ready)
  361.                 continue;
  362.             ready = GetName(savename);      /* what should we call it? */
  363.             switch(ready)
  364.                 {
  365.                     case 1:
  366.                         WriteCode(savename);    /* save */
  367.                         break;
  368.                     case 2:
  369.                         contin = FALSE;         /* quit */
  370.                         break;
  371.                     case 3:
  372.                         break;                    /* cancel */
  373.                 }
  374.         }
  375.     while(contin);
  376.     return;
  377. }
  378.  
  379. /*
  380.     pointer data (see GetClip(), below).
  381. */
  382.  
  383. UWORD chip hand_data[] =
  384.     {
  385.         0x0000,0x0000,        /* control words */
  386.         0x0000,0x0340,        /* data words     */
  387.         0x0340,0x0CB0,
  388.         0x0550,0x0AA8,
  389.         0x0558,0x0AA4,
  390.         0x02A8,0x0554,
  391.         0x02F8,0x6504,
  392.         0x61F8,0x9204,
  393.         0x73F8,0x8C04,
  394.         0x3FF8,0x4004,
  395.         0x1FF8,0x2004,
  396.         0x1FF0,0x2008,
  397.         0x07F0,0x1808,
  398.         0x01E0,0x0610,
  399.         0x00E0,0x0110,
  400.         0x00C0,0x0100,
  401.         0x0000,0x0000        /* more control words */
  402.     };
  403.  
  404.  
  405. /*
  406.     purpose of this routine ( GetClip() ) is to rubberband an area of the
  407.     picture to clip, or to scroll the bitmap around.  RubberBanding is
  408.     done with the left button, while scrolling is done with the right.
  409.  
  410.     Mouse moves are handled more quickly by "looking ahead" until either
  411.     the mouse stops moving or something besides a mousemove comes in.
  412.  
  413.     While scrolling around in the picture, the pointer is changed to a
  414.     hand (a la MacPaint) to indicate scrolling is active.  Otherwise,
  415.     the default system pointer is used.
  416.  
  417.     I should probably be shot for allowing a routine to be this large, but
  418.     it really isn't as bad as it looks...
  419. */
  420.  
  421. BOOL GetClip(clipit)
  422. struct Rectangle *clipit;
  423. {
  424.     struct IntuiMessage *msg = NULL;
  425.     struct IntuiMessage tempmsg;
  426.     BOOL mousedown = FALSE;         /* TRUE if left mouse down */
  427.     BOOL scrolldown = FALSE;        /* TRUE if right mouse down */
  428.     BOOL message_ready = FALSE;        /* TRUE if tempmsg has a valid message */
  429.     SHORT x,y;
  430.     SHORT dx,dy;
  431.     SHORT oldx,oldy;
  432.                                         /* clear the port first thing */
  433.     while(msg = (struct IntuiMessage *)GetMsg(window->UserPort))
  434.         ReplyMsg(msg);
  435.     oldx = oldy = x = y = 0;
  436.     do
  437.         {
  438.             oldx = x;
  439.             oldy = y;
  440.             if(!message_ready)
  441.                 {
  442.                     WaitPort(window->UserPort);             /* call me sometime */
  443.                     msg = (struct IntuiMessage *)GetMsg(window->UserPort);
  444.                     memcpy(&tempmsg,msg,(unsigned int)sizeof(struct IntuiMessage));
  445.                     ReplyMsg(msg);                          /* send it back */
  446.                 }
  447.             else
  448.                 message_ready = FALSE;    /* fixin' to use tempmsg */
  449.             x = tempmsg.MouseX;            /* where's the mouse? */
  450.             y = tempmsg.MouseY;
  451.             if(tempmsg.Class == MOUSEMOVE)  /* got a mouse in motion */
  452.                 {
  453.                     if(mousedown || scrolldown)     /* got a button down */
  454.                         {
  455.                             while(msg = (struct IntuiMessage *)GetMsg(window->UserPort))
  456.                                 {                /* look ahead while moving */
  457.                                     if(msg->Class == MOUSEMOVE)
  458.                                         {
  459.                                             x = msg->MouseX;
  460.                                             y = msg->MouseY;
  461.                                             ReplyMsg(msg);
  462.                                             continue;
  463.                                         }
  464.                                     else        /* not moving anymore */
  465.                                         {
  466.                                             memcpy(&tempmsg,msg,(unsigned int)sizeof(struct IntuiMessage));
  467.                                             ReplyMsg(msg);
  468.                                             message_ready = TRUE;
  469.                                             break;
  470.                                         }
  471.                                 }
  472.                         }
  473.                     if(mousedown)           /* clipping a piece already? */
  474.                         {
  475.                             clipit->MaxX = x + window->WLayer->Scroll_X;
  476.                             clipit->MaxY = y + window->WLayer->Scroll_Y;
  477.                             RubberBand(clipit,TRUE);        /* show it */
  478.                         }
  479.                     else if (scrolldown)    /* scrolling, are we? */
  480.                         {
  481.                             dx = (oldx - x);        /* get offsets */
  482.                             dy = (oldy - y);
  483. /* bounds checks */            if(window->WLayer->Scroll_X + dx <0)
  484.                                 dx = window->WLayer->Scroll_X;
  485.                             if(window->WLayer->Scroll_Y + dy <0)
  486.                                 dy = window->WLayer->Scroll_Y;
  487.                             if(window->WLayer->Scroll_X +dx > (window->WLayer->SuperBitMap->BytesPerRow * 8-window->Width))
  488.                                 dx = window->WLayer->SuperBitMap->BytesPerRow * 8-window->Width-window->WLayer->Scroll_X;
  489.                             if(window->WLayer->Scroll_Y + dy > window->WLayer->SuperBitMap->Rows-window->Height)
  490.                                 dy = window->WLayer->SuperBitMap->Rows-window->Height-window->WLayer->Scroll_Y;
  491.                             if(window->WLayer->SuperBitMap->BytesPerRow*8 <= window->Width)
  492.                                 dx = 0;
  493.                             if(window->WLayer->SuperBitMap->Rows <= window->Height)
  494.                                 dy = 0;
  495. /* Scroll BitMap */            ScrollLayer(window->WLayer->LayerInfo,window->WLayer,dx,dy);
  496.                             continue;
  497.                         }
  498.                 }
  499.             if(tempmsg.Class == MOUSEBUTTONS)
  500.                 {
  501.                     if((mousedown) && (tempmsg.Code == SELECTUP))
  502.                         {                    /* done drawing a clip */
  503.                             clipit->MaxX = x + window->WLayer->Scroll_X;    /* finished clip */
  504.                             clipit->MaxY = y + window->WLayer->Scroll_Y;
  505.                             mousedown = FALSE;            /* not clipping */
  506.                             RubberBand(clipit,FALSE);       /* erase border */
  507.                             if(clipit->MaxX <clipit->MinX)
  508.                                 {                        /* fix absolutes */
  509.                                     x = clipit->MaxX;    /* min and max     */
  510.                                     clipit->MaxX = clipit->MinX;
  511.                                     clipit->MinX = x;
  512.                                 }
  513.                             if(clipit->MaxY <clipit->MinY)
  514.                                 {
  515.                                     y = clipit->MaxY;
  516.                                     clipit->MaxY = clipit->MinY;
  517.                                     clipit->MinY = y;
  518.                                 }
  519.                             return TRUE;
  520.                         }
  521.                     if(!mousedown)
  522.                         {
  523.                             if(tempmsg.Code == SELECTDOWN)
  524.                                 {                    /* begin clipping */
  525.                                     clipit->MinX = x + window->WLayer->Scroll_X;
  526.                                     clipit->MinY = y + window->WLayer->Scroll_Y;
  527.                                     mousedown = TRUE;
  528.                                     continue;
  529.                                 }
  530.                             else if(tempmsg.Code == MENUDOWN)
  531.                                 {                    /* begin scrolling */
  532.                                     scrolldown = TRUE;
  533.                                     SetPointer(window,&hand_data,15,14,0,0);
  534.                                 }
  535.                             else if(tempmsg.Code == MENUUP)
  536.                                 {                    /* stop scrolling */
  537.                                     scrolldown = FALSE;
  538.                                     ClearPointer(window);   /* get that */
  539.                                 }                    /* hand outta there */
  540.                         }
  541.                 }
  542.             if(tempmsg.Class == VANILLAKEY)
  543.                 switch(toupper(tempmsg.Code))
  544.                     {
  545.                         case 'B':
  546.                             ScreenToBack(screen);
  547.                             break;
  548.                         case 'F':
  549.                             ScreenToFront(screen);
  550.                             break;
  551.                         case 'H':                               /* home the bitmap */
  552.                             ScrollLayer(window->WLayer->LayerInfo,
  553.                                 window->WLayer,0-window->WLayer->Scroll_X,0-window->WLayer->Scroll_Y);
  554.                             break;
  555.                         case 'Q':
  556.                             return TRUE;
  557.                     }
  558.         }
  559.     while(TRUE);
  560. }
  561.  
  562. void RubberBand(clipit,show)
  563. struct Rectangle *clipit;
  564. BOOL show;
  565. {
  566.     static BOOL already_drawn = FALSE;        /* for first time draw */
  567.     static struct Rectangle last;            /* for removing previous */
  568.  
  569.     SetDrMd(rport,COMPLEMENT);
  570.     if(already_drawn)
  571.         {                                    /* box exists - erase old */
  572.             Move(rport,last.MinX,last.MinY);
  573.             Draw(rport,last.MinX,last.MaxY);
  574.             Draw(rport,last.MaxX,last.MaxY);
  575.             Draw(rport,last.MaxX,last.MinY);
  576.             Draw(rport,last.MinX,last.MinY);
  577.         }
  578.     if(!show)
  579.         {
  580.             already_drawn = FALSE;
  581.             return;
  582.         }
  583.     else
  584.         {                                    /* draw the box */
  585.             Move(rport,clipit->MinX,clipit->MinY);
  586.             Draw(rport,clipit->MinX,clipit->MaxY);
  587.             Draw(rport,clipit->MaxX,clipit->MaxY);
  588.             Draw(rport,clipit->MaxX,clipit->MinY);
  589.             Draw(rport,clipit->MinX,clipit->MinY);
  590.             already_drawn = TRUE;
  591.         }
  592.     last.MinX = clipit->MinX;                /* save for next time */
  593.     last.MinY = clipit->MinY;
  594.     last.MaxX = clipit->MaxX;
  595.     last.MaxY = clipit->MaxY;
  596.     return;
  597. }
  598.  
  599. /*
  600.     The following structures are all used in the GetName routine.
  601.     The routine opens another window on top of the graphic image,
  602.     with a string gadget for the filename to save, and five boolean
  603.     gadgets (IMAGE, BITMAP, SAVE, CANCEL, and QUIT).
  604. */
  605.  
  606. struct TextAttr makecfont = { "topaz.font", 8, FS_NORMAL, FPF_ROMFONT };
  607.  
  608. struct IntuiText chip nametext =
  609.     {    1,0,JAM1,2,2,&makecfont,NULL,NULL    };    /* fill out later */
  610.  
  611. SHORT chip namehilites[] = 
  612.     { 
  613.         0,  9, 
  614.         0,  0, 
  615.       241,  0, 
  616.     };
  617.  
  618. SHORT chip nameshadows[] =
  619.     {
  620.         241, 1,
  621.         241, 9,
  622.           1, 9,
  623.     };
  624.      
  625. struct Border chip nameborder2 = { -1,-1,3,0,JAM1,3,nameshadows,NULL };
  626. struct Border chip nameborder  = { -1,-1,1,0,JAM1,3,namehilites,&nameborder2 };
  627.     
  628. struct Border chip namehit2 = { -1,-1,1,0,JAM1,3,nameshadows,NULL };
  629. struct Border chip namehit  = { -1,-1,3,0,JAM1,3,namehilites,&namehit2 };
  630.     
  631. char namebuffer[40];
  632. char undobuffer[40];
  633. struct StringInfo chip nameinfo =                /* updated later  */
  634.     {
  635.         namebuffer,
  636.         undobuffer,
  637.         0,41,                /* buffer pos, max #chars. */
  638.         0,                    /* display position       */
  639.         0,0,0,0,0,NULL,0L,NULL,     /* Intuition handles these... */
  640.     };
  641.  
  642. /* these are for the BOOLGADGETS */
  643.  
  644. SHORT chip gadget_hilites[] =            /* used for 3d look */
  645.     {
  646.           0, 17,
  647.           0,  0,
  648.          54,  0,
  649.     };
  650.     
  651. SHORT chip gadget_shadows[] =            /* ditto            */
  652.     {
  653.          54,  1,
  654.          54, 17,
  655.           0, 17,
  656.     };
  657.         
  658. struct Border chip gadget_border_2 = { 0,0,1,0,JAM1,3,gadget_hilites,NULL };
  659. struct Border chip gadget_border   = { 0,0,3,0,JAM1,3,gadget_shadows,&gadget_border_2 };
  660.  
  661. struct Border chip gadget_hit_2    = { 0,0,3,0,JAM1,3,gadget_hilites,NULL };
  662. struct Border chip gadget_hit      = { 0,0,1,0,JAM1,3,gadget_shadows,&gadget_hit_2 };
  663.  
  664. struct IntuiText chip bitmap_text_shadow =
  665.     {
  666.         1,0,            /* FrontPen, BackPen */
  667.         JAM1,            /* DrawMode             */
  668.         4,5,            /* left, top */
  669.         &makecfont,        /* font */
  670.         "BITMAP",        /* text */
  671.         NULL            /* next */
  672.     };
  673. struct IntuiText chip bitmap_text =
  674.     {
  675.         3,0,            /* FrontPen, BackPen */
  676.         JAM1,            /* DrawMode */
  677.         3,5,            /* left, top */
  678.         &makecfont,        /* font */
  679.         "BITMAP",       /* the text */
  680.         &bitmap_text_shadow,            /* next text */
  681.     };
  682.  
  683. struct Gadget chip bitmap_gadget =
  684.     {
  685.         NULL,                    /* next gadget (none) */
  686.         133,21,                 /* left, top edges    */
  687.         54,17,                    /* width, height      */
  688.         GADGHIMAGE,                /* flag for highlighting */
  689.         RELVERIFY|TOGGLESELECT, /* make sure they really want it */
  690.         BOOLGADGET,                /* boolean gadget */
  691.         (APTR) &gadget_border,  /* GadgetRender */
  692.         (APTR) &gadget_hit,        /* SelectRender */
  693.         &bitmap_text,            /* Gadget Text */
  694.         NULL,NULL,                /* Mutual Exclude, special Info */
  695.         6,NULL                    /* ID, Userdata */
  696.     };
  697.  
  698. struct IntuiText chip image_text_shadow =
  699.     {
  700.         1,0,            /* FrontPen, BackPen */
  701.         JAM1,            /* DrawMode */
  702.         8,5,            /* left, top */
  703.         &makecfont,        /* font */
  704.         "IMAGE",        /* the text */
  705.         NULL,            /* next text */
  706.     };
  707.  
  708.  
  709. struct IntuiText chip image_text =
  710.     {
  711.         3,0,            /* FrontPen, BackPen */
  712.         JAM1,            /* DrawMode */
  713.         7,5,            /* left, top */
  714.         &makecfont,        /* font */
  715.         "IMAGE",        /* the text */
  716.         &image_text_shadow,            /* next text */
  717.     };
  718.  
  719. struct Gadget chip image_gadget =
  720.     {
  721.         &bitmap_gadget,         /* next gadget (none) */
  722.         71,21,                    /* left, top edges    */
  723.         54,17,                    /* width, height      */
  724.         GADGHIMAGE,                /* flag for highlighting */
  725.         RELVERIFY|TOGGLESELECT, /* make sure they really want it */
  726.         BOOLGADGET,                /* boolean gadget */
  727.         (APTR) &gadget_border,  /* GadgetRender */
  728.         (APTR) &gadget_hit,     /* SelectRender */
  729.         &image_text,            /* Gadget Text */
  730.         0xFFFF,NULL,            /* Mutual Exclude, special Info */
  731.         5,NULL                    /* ID, Userdata */
  732.     };
  733.  
  734. struct IntuiText chip save_text_shadow =
  735.     {
  736.         1,0,            /* FrontPen, BackPen */
  737.         JAM1,            /* DrawMode */
  738.         13,5,            /* left, top */
  739.         &makecfont,        /* font */
  740.         "SAVE",                 /* the text */
  741.         NULL,            /* next text */
  742.     };
  743.  
  744.  
  745. struct IntuiText chip save_text =
  746.     {
  747.         3,0,            /* FrontPen, BackPen */
  748.         JAM1,            /* DrawMode */
  749.         12,5,            /* left, top */
  750.         &makecfont,            /* font */
  751.         "SAVE",         /* the text */
  752.         &save_text_shadow,            /* next text */
  753.     };
  754.  
  755. struct Gadget chip save_gadget =
  756.     {
  757.         &image_gadget,            /* next gadget (none) */
  758.         44,41,                    /* left, top edges    */
  759.         54,17,                    /* width, height      */
  760.         GADGHIMAGE,                /* flag for highlighting */
  761.         RELVERIFY,                /* make sure they really want it */
  762.         BOOLGADGET,                /* boolean gadget */
  763.         (APTR) &gadget_border,  /* GadgetRender */
  764.         (APTR) &gadget_hit,        /* SelectRender */
  765.         &save_text,                /* Gadget Text */
  766.         NULL,NULL,                /* Mutual Exclude, special Info */
  767.         1,NULL                    /* ID, Userdata */
  768.     };
  769.  
  770. struct IntuiText chip cancel_text_shadow =
  771.     {
  772.         1,0,            /* FrontPen, BackPen */
  773.         JAM1,            /* DrawMode */
  774.         5, 5,            /* left, top */
  775.         &makecfont,            /* font */
  776.         "CANCEL",       /* the text */
  777.         NULL,            /* next text */
  778.     };
  779.  
  780.  
  781. struct IntuiText chip cancel_text =
  782.     {
  783.         3,0,            /* FrontPen, BackPen */
  784.         JAM1,            /* DrawMode */
  785.         4, 5,            /* left, top */
  786.         &makecfont,            /* font */
  787.         "CANCEL",       /* the text */
  788.         &cancel_text_shadow,            /* next text */
  789.     };
  790.  
  791. struct Gadget chip cancel_gadget =
  792.     {
  793.         &save_gadget,            /* next gadget */
  794.         104,41,                    /* left, top edges    */
  795.         54,17,                    /* width, height      */
  796.         GADGHIMAGE,                /* flag for highlighting */
  797.         RELVERIFY,                /* make sure they really want it */
  798.         BOOLGADGET,                /* boolean gadget */
  799.         (APTR) &gadget_border,  /* GadgetRender */
  800.         (APTR) &gadget_hit,        /* SelectRender */
  801.         &cancel_text,            /* Gadget Text */
  802.         NULL,NULL,                /* Mutual Exclude, special Info */
  803.         3,NULL                    /* ID, Userdata */
  804.     };
  805.  
  806. struct IntuiText chip quit_text_shadow =
  807.     {
  808.         1,0,            /* FrontPen, BackPen */
  809.         JAM1,            /* DrawMode */
  810.         13, 5,            /* left, top */
  811.         &makecfont,            /* font */
  812.         "QUIT",         /* the text */
  813.         NULL,            /* next text */
  814.     };
  815.  
  816.  
  817. struct IntuiText chip quit_text =
  818.     {
  819.         3,0,            /* FrontPen, BackPen */
  820.         JAM1,            /* DrawMode */
  821.         12, 5,            /* left, top */
  822.         &makecfont,            /* font */
  823.         "QUIT",         /* the text */
  824.         &quit_text_shadow,            /* next text */
  825.     };
  826.  
  827. struct Gadget chip quit_gadget =
  828.     {
  829.         &cancel_gadget,         /* next gadget (none) */
  830.         163,41,                 /* left, top edges    */
  831.         54,17,                    /* width, height      */
  832.         GADGHIMAGE,                /* flag for highlighting */
  833.         RELVERIFY,                /* make sure they really want it */
  834.         BOOLGADGET,                /* boolean gadget */
  835.         (APTR) &gadget_border,  /* GadgetRender */
  836.         (APTR) &gadget_hit,        /* SelectRender */
  837.         &quit_text,                /* Gadget Text */
  838.         NULL,NULL,                /* Mutual Exclude, special Info */
  839.         2,NULL                    /* ID, Userdata */
  840.     };
  841.  
  842. struct Gadget chip name_gadget =
  843.     {
  844.         &quit_gadget,
  845.         8,10,
  846.         240,10,
  847.         GADGHIMAGE,
  848.         RELVERIFY,
  849.         STRGADGET,
  850.         (APTR) &nameborder,
  851.         (APTR) &namehit,
  852.         &nametext,
  853.         NULL,
  854.         (APTR)&nameinfo,
  855.         4,NULL,
  856.     };
  857.  
  858. struct NewWindow newnamewindow =
  859.     {
  860.         0,0,                /* left, top */
  861.         260,75,             /* width, height */
  862.         0,1,                /* detail pen, block pen */
  863.         INACTIVEWINDOW|WINDOWDRAG|GADGETUP,/* just use gadgets, with title bar */
  864.         SMART_REFRESH|ACTIVATE|GIMMEZEROZERO,    /* IDCMP stuff */
  865.         &name_gadget,        /* gadget list */
  866.         NULL,                /* checkmark */
  867.         "Enter SAVE filename",  /* title */
  868.         NULL,                /* screen (fill later) */
  869.         NULL,                /* bitmap */
  870.         0,0,0,0,            /* max and min sizes */
  871.         CUSTOMSCREEN,        /* screen type */
  872.     };
  873.  
  874. /*
  875.     GetName() is another of those rather bloated routines.  It gets a
  876.     filename for the save, lets you specify Image or Bitmap output, and
  877.     allows you to save it, cancel and continue, or quit the program
  878. */
  879.  
  880. UBYTE GetName(name)
  881. char *name;
  882. {
  883.     struct Window *namewindow;
  884.     struct IntuiMessage *msg;
  885.     struct Gadget *gadg;
  886.     UBYTE gadget_number;
  887.     UWORD tempcolors[] = { 0x0888, 0x0FFF, 0x0F00, 0x0000 };
  888.     ULONG class;
  889.  
  890.     strcpy(namebuffer,name);
  891.     newnamewindow.Screen = screen;
  892.     newnamewindow.LeftEdge = screen->Width/2-130;    /* center the window */
  893.     newnamewindow.TopEdge = screen->Height/2-40;    /* visually, that is */
  894.     image_gadget.Flags &= ~SELECTED;
  895.     bitmap_gadget.Flags &= ~SELECTED;
  896.     LoadRGB4(&screen->ViewPort,tempcolors,4);               /* set some colors */
  897.     namewindow = (struct Window *)OpenWindow(&newnamewindow);
  898.     if(!namewindow)
  899.         {
  900.             printf("\nError opening filename window!!\n");
  901.             return 3;
  902.         }
  903.     SetRast(namewindow->RPort,2);    
  904.     SetAPen(namewindow->RPort,3);    
  905.     Move(namewindow->RPort,260,0);
  906.     Draw(namewindow->RPort,0,0);
  907.     Draw(namewindow->RPort,0,75);
  908.     SetAPen(namewindow->RPort,1);    
  909.     Draw(namewindow->RPort,260,75);
  910.     Draw(namewindow->RPort,260,1);
  911.     RefreshGadgets(&name_gadget,namewindow,NULL);    
  912.     do
  913.         {
  914.             WaitPort(namewindow->UserPort);
  915.             msg = (struct IntuiMessage *)GetMsg(namewindow->UserPort);
  916.             class = msg->Class;            /* I love messages with class */
  917.             if(class != GADGETUP)           /* I only care about gadgets */
  918.                 continue;
  919.             gadg = (struct Gadget *)msg->IAddress;  /* what gadget? */
  920.             gadget_number = gadg->GadgetID;         /* oh, that gadget */
  921.             ReplyMsg(msg);
  922.             switch(gadget_number)
  923.                 {
  924.                     case 1:
  925.                     case 2:
  926.                     case 3:
  927.                         CloseWindow(namewindow);
  928.                         strcpy(name,namebuffer);                /* restore colors */
  929.                         LoadRGB4(&screen->ViewPort,colortable,colorcount);
  930.                         return gadget_number;
  931.                     case 4:             /* could lump this in with case 3 */
  932.                         break;            /* if you wanted to...          */
  933.                     case 5:
  934.                         IMAGE_OUT = TRUE;    /* hit the Image gadget */
  935.                         image_gadget.Flags |= SELECTED;
  936.                         bitmap_gadget.Flags &= ~SELECTED;
  937.                         RefreshGadgets(&image_gadget,namewindow,NULL);
  938.                         break;
  939.                     case 6:
  940.                         IMAGE_OUT = FALSE;    /* hit the BitMap gadget */
  941.                         image_gadget.Flags &= ~SELECTED;
  942.                         bitmap_gadget.Flags |= SELECTED;
  943.                         RefreshGadgets(&image_gadget,namewindow,NULL);
  944.                         break;
  945.                 }
  946.         }
  947.     while(TRUE);
  948. }
  949.  
  950.  
  951. /*
  952.     WriteCode() handles the actual code generation for whatever was clipped
  953.     out.  If nothing was clipped out, it ignores the request.
  954.     It takes the easy way out for word-alignment of the clipped image by
  955.     creating an off-screen bitmap and using the blitter to yank out the
  956.     image so it will align properly.
  957. */
  958.  
  959. void WriteCode(savename)
  960. char *savename;
  961. {
  962.     SHORT pixwide,pixhigh;
  963.     SHORT x,y,count,planes;
  964.     struct BitMap tempmap;
  965.     char basename[40];
  966.     ULONG memsize;
  967.  
  968.     outputfile = fopen(savename,"w");
  969.     if(!outputfile)
  970.         {
  971.             printf("\nUnable to open save file!!\n");
  972.             return;
  973.         }
  974.     pixwide = clip.MaxX - clip.MinX + 1;
  975.     pixhigh = clip.MaxY - clip.MinY + 1;
  976.     if(!pixwide && !pixhigh)                /* give me something to work with, eh? */
  977.         return;
  978.     x = clip.MinX;
  979.     y = clip.MinY;
  980.     planes = rport->BitMap->Depth;
  981.     InitBitMap(&tempmap,planes,pixwide,pixhigh);
  982.     memsize = tempmap.BytesPerRow * tempmap.Rows;
  983.     for(count=0;count<planes;count++)
  984.         {
  985.             tempmap.Planes[count] = (PLANEPTR)AllocMem(memsize,MEMF_CHIP|MEMF_CLEAR);
  986.             if(tempmap.Planes[count] == NULL)
  987.                 {
  988.                     for(planes=0;planes<count;planes++)
  989.                         FreeMem(tempmap.Planes[count],memsize);
  990.                     break;
  991.                 }
  992.         }                                /* now grab the clipped image */
  993.     BltBitMap(rport->BitMap,x,y,&tempmap,0,0,pixwide,pixhigh,0xC0,0xFF);
  994.  
  995. /*
  996.     Now tempmap has the word-aligned image we want, so we can just
  997.         write it out.  Simple, eh?
  998. */
  999.  
  1000.     FindBaseName(basename,savename);
  1001.     if(IMAGE_OUT)
  1002.         ImageOut(&tempmap,basename,pixwide,pixhigh,planes);
  1003.     else
  1004.         BitMapOut(&tempmap,basename,pixwide,pixhigh,planes);
  1005.     for(count=0;count<planes;count++)                       /* free up some memory */
  1006.         FreeMem(tempmap.Planes[count],memsize);
  1007.     return;
  1008. }
  1009.  
  1010.  
  1011. /*
  1012.     FindBaseName just takes a filename and rips out the base part of it,
  1013.     minus any path information or extensions
  1014.     
  1015.     This function was simplified, corrected, and rewritten by Mike Seinz.
  1016.     Thanks, Mike.
  1017. */
  1018.  
  1019. void FindBaseName(base,name)
  1020. char *base, *name;
  1021. {
  1022.     register char *tcp, *cp;
  1023.  
  1024.     cp = name;
  1025.     if ((tcp = strrchr(cp, ':')))
  1026.         cp = tcp+1;
  1027.     if ((tcp = strrchr(cp, '/')))
  1028.         *cp = 0;
  1029.     if ((tcp = strchr(base, '.')))
  1030.         *tcp = 0;
  1031.  
  1032.     strcpy (base, cp);
  1033. }
  1034.  
  1035.  
  1036. /*
  1037.     ImageOut() writes the actual code for an Image structure.  It does
  1038.     one bitplane at a time, by row, by word.  Pretty simple, really.
  1039. */
  1040.  
  1041. void ImageOut(bitmap,base,width,height,depth)
  1042. struct BitMap *bitmap;
  1043. char *base;
  1044. SHORT width,height,depth;
  1045. {
  1046.     SHORT planes,row,word,pos = 0;
  1047.     USHORT *planeptr;
  1048.  
  1049.     fprintf(outputfile,"/*\n\tImage Structure definitions for %s \n*/\n\n",base);
  1050.     fprintf(outputfile,"USHORT ");
  1051.     if(chipkeyword)
  1052.         fprintf(outputfile,"chip ");
  1053.     fprintf(outputfile,"%s_data[] = \n\t{\n\t\t",base);
  1054.     for(planes=0;planes<depth;planes++)
  1055.         {
  1056.             fprintf(outputfile,"\n\t\t/*  Plane %d */\n\t\t",planes);
  1057.             pos=0;
  1058.             for(row=0;row<bitmap->Rows;row++)
  1059.                 {
  1060.                     planeptr = (USHORT *)bitmap->Planes[planes]+((row*bitmap->BytesPerRow)/2);
  1061.                     for(word=0;word<((bitmap->BytesPerRow)/2);word++)
  1062.                         {
  1063.                             fprintf(outputfile,"0x%04x, ",planeptr[word]);
  1064.                             if(++pos>6)
  1065.                                 {
  1066.                                     pos = 0;
  1067.                                     fprintf(outputfile,"\n\t\t");
  1068.                                 }
  1069.                         }
  1070.                 }
  1071.         }
  1072.     fprintf(outputfile,"\n\t};\n");
  1073.     fprintf(outputfile,"struct Image ");
  1074.     if(chipkeyword)
  1075.         fprintf(outputfile,"chip ");
  1076.     fprintf(outputfile,"%s_image = \n\t{\n\t\t",base);
  1077.     fprintf(outputfile,"0,0,                        /*  LeftEdge, TopEdge    */\n\t\t");
  1078.     fprintf(outputfile,"%d, %d, %d,         /*  Width, Height, Depth */\n\t\t",width,height,depth);
  1079.     fprintf(outputfile,"%s_data,            /*  ImageData  */\n\t\t",base);
  1080.     fprintf(outputfile,"0xFF,0,                     /*  PlanePick, PlaneOnOff */\n\t\t");
  1081.     fprintf(outputfile,"NULL,                       /*  NextImage */\n\t};\n\n");
  1082.     fprintf(outputfile,"\n/*  This data created by the MakeC program  */");
  1083.     fprintf(outputfile,"\n/*  MakeC (c) 1990 by Robert Kesterson      */");
  1084.     fprintf(outputfile,"\n/*                    6418 30th Street      */");
  1085.     fprintf(outputfile,"\n/*                    Lubbock, TX 79407     */");
  1086.     fprintf(outputfile,"\n/*                    (806)-792-3639        */");
  1087.     fprintf(outputfile,"\n/*               BIX: rkesterson            */\n\n");
  1088.     fclose(outputfile);
  1089.     return;
  1090. }
  1091.  
  1092. /*
  1093.     BitMapOut() is just like ImageOut, except it does it in BitMap
  1094.     format, and by bytes rather than words.
  1095. */
  1096.  
  1097. void BitMapOut(bitmap,base,width,height,depth)
  1098. struct BitMap *bitmap;
  1099. char *base;
  1100. SHORT width,height,depth;
  1101. {
  1102.     SHORT planes,row,byte,pos = 0;
  1103.     UWORD count;
  1104.  
  1105.     fprintf(outputfile,"/*\n\tBitMap Structure definitions for %s \n*/\n\n",base);
  1106.     for(planes=0;planes<depth;planes++)
  1107.         {
  1108.             fprintf(outputfile,"\nUBYTE ");
  1109.             if(chipkeyword)
  1110.                 fprintf(outputfile,"chip ");
  1111.             fprintf(outputfile,"%s_plane%d[] = \n\t{\n\t\t",base,planes);
  1112.             for(row=0;row<bitmap->Rows;row++)
  1113.                 for(byte=0;byte<bitmap->BytesPerRow;byte++)
  1114.                     {
  1115.                         fprintf(outputfile,"0x%02x, ",(UBYTE)*(bitmap->Planes[planes]+(row*bitmap->BytesPerRow)+byte));
  1116.                         if(++pos>10)
  1117.                             {
  1118.                                 pos = 0;
  1119.                                 fprintf(outputfile,"\n\t\t");
  1120.                             }
  1121.                     }
  1122.             fprintf(outputfile,"\n\t};\n\n");
  1123.         }
  1124.     fprintf(outputfile,"struct BitMap ");
  1125.     if(chipkeyword)
  1126.         fprintf(outputfile,"chip ");
  1127.     fprintf(outputfile,"%s_bitmap = \n\t{\n\t\t",base);
  1128.     fprintf(outputfile,"%u,                 /*  BytesPerRow  */\n\t\t",bitmap->BytesPerRow);
  1129.     fprintf(outputfile,"%u,                 /*  Rows  */\n\t\t",bitmap->Rows);
  1130.     fprintf(outputfile,"%02x,               /*  Flags  */\n\t\t",bitmap->Flags);
  1131.     fprintf(outputfile,"%d,                 /*  Depth  */\n\t\t",depth);
  1132.     fprintf(outputfile,"0,                  /*  pad    */\n\t\t");
  1133.     for(count=0;count<depth;count++)
  1134.         fprintf(outputfile,"%s_plane%d,         /*  plane data  */\n\t\t",base,count);
  1135.     for(;count<=7;count++)
  1136.         fprintf(outputfile,"NULL,\n\t\t");
  1137.     fprintf(outputfile,"\n\t};\n\n");
  1138.     fprintf(outputfile,"\n/*  This data created by the MakeC program  */");
  1139.     fprintf(outputfile,"\n/*  MakeC (c) 1990 by Robert Kesterson      */");
  1140.     fprintf(outputfile,"\n/*                    6418 30th Street      */");
  1141.     fprintf(outputfile,"\n/*                    Lubbock, TX 79407     */");
  1142.     fprintf(outputfile,"\n/*                    (806)-792-3639        */");
  1143.     fprintf(outputfile,"\n/*               BIX: rkesterson            */\n\n");
  1144.     fclose(outputfile);
  1145.     return;
  1146. }
  1147.  
  1148.  
  1149. /*
  1150.     Create_bitmap() is a pretty generic routine to allocate and initialize
  1151.     a bitmap.
  1152. */
  1153.  
  1154. struct BitMap *create_bitmap(width,height,depth)
  1155. UWORD width,height;
  1156. UBYTE depth;
  1157. {
  1158.     short i, error_flag = (SHORT)FALSE;
  1159.     struct BitMap *pbitmap = NULL;
  1160.     unsigned char *planepointer;
  1161.  
  1162.     if((depth>0L) && (width>0L) && (height>0L))
  1163.         {
  1164.             pbitmap = (struct BitMap *)AllocMem(sizeof(struct BitMap),
  1165.                         MEMF_CHIP | MEMF_CLEAR);
  1166.             if(pbitmap != NULL)
  1167.                 {
  1168.                     InitBitMap(pbitmap,depth,width,height);
  1169.                     for(i=0;i<depth;i++)
  1170.                         {
  1171.                             planepointer = (PLANEPTR)AllocMem(RASSIZE(width,height),MEMF_CHIP|MEMF_CLEAR);
  1172.                             if(planepointer)
  1173.                                 pbitmap->Planes[i] = planepointer;
  1174.                             else
  1175.                                 error_flag = TRUE;
  1176.                         }
  1177.                 }
  1178.         }
  1179.     if(error_flag == TRUE)
  1180.         {
  1181.             close_bitmap(pbitmap);
  1182.             pbitmap = NULL;
  1183.         }
  1184.     return(pbitmap);
  1185. }
  1186.  
  1187. /*
  1188.     close_bitmap() just frees up all the memory in a BitMap that was
  1189.     previously allocated with create_bitmap().
  1190. */
  1191.  
  1192. void close_bitmap(pbitmap)
  1193. struct BitMap *pbitmap;
  1194. {
  1195.     unsigned char *planepointer;
  1196.     unsigned long depth,width,height;
  1197.     short i;
  1198.  
  1199.     if(pbitmap != NULL)
  1200.         {
  1201.             depth = pbitmap->Depth;
  1202.             width = pbitmap->BytesPerRow * 8;
  1203.             height = pbitmap->Rows;
  1204.             for ( i=0; i<depth; i++)
  1205.                 {
  1206.                     planepointer = pbitmap->Planes[i];
  1207.                     if(planepointer != NULL)
  1208.                         FreeMem(planepointer,RASSIZE(width,height));
  1209.                     }
  1210.             FreeMem(pbitmap,sizeof(struct BitMap));
  1211.         }
  1212. }
  1213.  
  1214.